import tkinter as tk
import random
from math import sqrt
from tkinter import messagebox

runPart=1
year = 0
timeRate=1
# 定义等级名称
LEVEL_NAMES = []
BASE_LEVELS = [
    "江湖好手", "练气", "筑基", "金丹", "元婴", "化神", "炼虚", "合体", "大乘", "渡劫", "金仙"
]
SUB_LEVELS = ["前期", "中期", "后期", "圆满"]

for level in BASE_LEVELS:
    if level == "江湖好手":
        LEVEL_NAMES.append(level)
    else:
        for sub_level in SUB_LEVELS:
            LEVEL_NAMES.append(f"{level}{sub_level}")

# 定义每个等级对应的生命恢复量
LEVEL_HEAL_AMOUNTS = [10] * len(LEVEL_NAMES)

locations = [
    "群山", "湖", "沙漠", "山谷", "海岛", "森林", "洞穴", "遗迹", "古战场", "城镇"
]

subjects = [
    "神秘灵脉", "炼丹师", "上古法宝", "妖兽", "修仙门派", "奇异天象", "宝藏", "秘籍", "神器", "灵植"
]

# 增加更多事件描述
events = [
    # 神秘灵脉相关
    "突然出现，灵气四溢，引得不少修仙者前来探寻。",
    "被发现，周围灵气异常浓郁，引得附近妖兽纷纷聚集。",
    "灵脉异动，引发了一场小型的灵气风暴。",
    # 炼丹师相关
    "炼制出了不少神奇丹药，吸引了众多炼丹爱好者。",
    "与其他炼丹师展开了一场炼丹比试，引得众人围观。",
    "研发出一种新的炼丹配方，引起炼丹界轰动。",
    # 上古法宝相关
    "封印松动，可能会现世，引发各方关注。",
    "被一股神秘力量唤醒，散发出微弱的光芒。",
    "传出阵阵神秘的波动，似乎在寻找有缘人。",
    # 妖兽相关
    "突然闯入，烧杀抢掠，修仙者们纷纷前往降妖除魔。",
    "修炼突破，实力大增，开始袭击附近的修仙村落。",
    "召唤出一群小妖兽，组成兽潮进攻城镇。",
    # 修仙门派相关
    "举办论道大会，广邀各路高手参加。",
    "遭遇其他门派挑衅，双方剑拔弩张。",
    "派遣弟子外出历练，寻找机缘。",
    # 奇异天象相关
    "出现，似乎预示着一场重大变故即将发生。",
    "持续数日不散，引得修仙者们纷纷猜测其寓意。",
    "伴随着奇异的声音，让人不寒而栗。",
    # 宝藏相关
    "被发现，周围灵气异常浓郁。",
    "被盗，门派悬赏缉拿盗贼。",
    "其所在之处被设下重重陷阱，难以靠近。",
    # 秘籍相关
    "出世，散发出强大的力量波动。",
    "被人偶然翻开，其中的文字闪烁光芒。",
    "流出的气息引得众多修仙者抢夺。",
    # 神器相关
    "突然出现，灵气四溢，引得不少修仙者前来探寻。",
    "异动，周围空间出现扭曲现象。",
    "被神秘阵法封印，需解开阵法才能获得。",
    # 灵植相关
    "成熟，散发出诱人的香气。",
    "被一群妖兽守护，难以采摘。",
    "灵植的种子突然发芽，生长速度惊人。"
]

# 定义元素与事件的映射关系
subject_event_mapping = {
    "神秘灵脉": events[:3],
    "炼丹师": events[3:6],
    "上古法宝": events[6:9],
    "妖兽": events[9:12],
    "修仙门派": events[12:15],
    "奇异天象": events[15:18],
    "宝藏": events[18:21],
    "秘籍": events[21:24],
    "神器": events[24:27],
    "灵植": events[27:]
}

result = []
for loc in locations:
    for sub in subjects:
        for event in subject_event_mapping[sub]:
            result.append([loc, sub, event])

# 新增减少生命值和寿元的事件
bad_events = [
    "散发着诡异的气息，让你不慎吸入，寿元减少了 {} 年。",
    "引发了一场灾难，波及到你，寿元减少了 {} 年。",
    "突然爆发出一股阴寒之力，侵入你的身体，寿元折损了 {} 年。",
    "触发了古老的诅咒，你的寿元被莫名剥夺了 {} 年。",
    "被神秘的黑暗能量笼罩，每呼吸一次，寿元便减少 {} 年。",
    "周围空间扭曲产生强大压力，压迫你的生机，寿元减少了 {} 年。",
    "遭遇了致命的幻术攻击，在幻境中消耗大量生机，寿元缩短了 {} 年。",
    "误食了带有诅咒的灵物，寿元急剧下降了 {} 年。",
    "陷入了时间乱流，短暂迷失后，寿元已流逝了 {} 年。",
    "被邪恶法阵的力量波及，经脉受损，寿元减少了 {} 年。"
]

lucky_events = [
    "散发着神秘的光芒，让你眼前一亮，寿元增加了 {} 年。",
    "触发了古老的祝福，你的寿元被莫名增长了 {} 年。",
    "突然爆发出一股阳光之力，侵入你的身体，寿元增加了 {} 年。",
    "被神秘的光能量笼罩，每呼吸一次，寿元便增加了 {} 年。",  # 新增恢复生命值事件
]
class Player:
    def __init__(self):
        self.level = 0  # 从 0 开始对应练气
        self.exp = 0
        self.hp = 100
        self.attack = 20
        self.gold = 0
        self.lifespan = 100  # 初始寿元
        self.max_hp = 100  # 新增最大生命值属性

    def train(self):
        global year
        exp_gained = int(random.randint(10, 20)*(sqrt(self.level)+1))
        gold_gained = int(random.randint(5, 10)*(sqrt(self.level)+1))
        self.exp += exp_gained
        self.gold += gold_gained
        year += 1
        self.lifespan -= random.randint(1, 7)  # 减少寿元
        self.heal()  # 训练时恢复生命
        result = f"第{year}年,你修炼了一番，获得了 {exp_gained} 点真元和 {gold_gained} 枚金币。"
        if self.exp >= (self.level*self.level + 1) * 100:
            result += "\n" + self.level_up()
        return result

    def explore(self):
        global year
        year += 1
        event = random.randint(1, 4)  # 增加一个事件用于恢复生命值
        if event == 1:
            monster_hp = random.randint(50, 80)+self.level*20
            monster_attack = random.randint(10, 15)+self.level*15
            result = f"第{year}年，你在探索时遇到了一只怪物，它的生命值为 {monster_hp}，攻击力为 {monster_attack}。\n"
            while self.hp > 0 and monster_hp > 0:
                monster_hp -= self.attack
                result += f"你攻击了怪物，怪物剩余生命值: {monster_hp}\n"
                if monster_hp <= 0:
                    exp_gained = random.randint(15, 25)
                    gold_gained = random.randint(8, 12)
                    self.exp += exp_gained
                    self.gold += gold_gained
                    result += f"你成功击败了怪物，获得了 {exp_gained} 点真元和 {gold_gained} 枚金币。"
                    if self.exp >= (self.level*self.level + 1) * 100:
                        result += "\n" + self.level_up()
                    break
                self.hp -= monster_attack
                result += f"怪物攻击了你，你剩余生命值: {self.hp}\n"
                if self.hp <= 0:
                    result += "你被怪物击败，生命值耗尽，死亡。"
                    break
        elif event == 2:
            gold_gained = random.randint(20, 30)
            self.gold += gold_gained
            result = f"第{year}年，你找到了一个宝藏，获得了 {gold_gained} 枚金币。"
        elif event == 3:
            result = f"第{year}年，你这次探索什么也没发现。"
        else:
            heal_amount = random.randint(20, 50)
            self.hp = min(self.hp + heal_amount, self.max_hp)
            result = f"第{year}年，你在探索中找到了一颗疗伤圣药，恢复了 {heal_amount} 点生命值，当前生命值: {self.hp}。"
        self.heal()  # 探索时恢复生命
        return result

    def challenge(self):
        global year
        year += 1
        if self.level < 1:  # 筑基期才能挑战
            return f"第{year}年，你的修为还不够，无法挑战。"
        enemy_hp = random.randint(150, 200)
        enemy_attack = random.randint(20, 30)
        result = f"第{year}年，你挑战了一个强大的敌人，它的生命值为 {enemy_hp}，攻击力为 {enemy_attack}。\n"
        while self.hp > 0 and enemy_hp > 0:
            enemy_hp -= self.attack
            result += f"你攻击了敌人，敌人剩余生命值: {enemy_hp}\n"
            if enemy_hp <= 0:
                exp_gained = random.randint(30, 50)
                gold_gained = random.randint(30, 50)
                self.exp += exp_gained
                self.gold += gold_gained
                result += f"你成功击败了敌人，获得了 {exp_gained} 点真元和 {gold_gained} 枚金币。"
                if self.exp >= (self.level*self.level + 1) * 100:
                    result += "\n" + self.level_up()
                break
            self.hp -= enemy_attack
            result += f"敌人攻击了你，你剩余生命值: {self.hp}\n"
            if self.hp <= 0:
                result += "你被敌人击败，生命值耗尽，死亡。"
                break
        self.heal()  # 挑战时恢复生命
        return result

    def level_up(self):
        self.level = min(self.level + 1, len(LEVEL_NAMES) - 1)
        self.exp = 0
        self.hp += 50
        self.max_hp += 50*self.level  # 升级时增加最大生命值
        self.attack += 10
        self.lifespan += 50 * self.level

        return f"恭喜你，升级到了 {LEVEL_NAMES[self.level]}！你的生命值提升到了 {self.hp}，攻击力提升到了 {self.attack}。"

    def show_status(self):
        return f"当前修为: {LEVEL_NAMES[self.level]}\n当前真元: {self.exp}/{100*(self.level*self.level+1)}\n当前生命值: {self.hp}/{self.max_hp}\n当前攻击力: {self.attack}\n当前金币: {self.gold}\n当前寿元: {self.lifespan}\n当前时间倍率: {timeRate}X"

    def reduce_lifespan(self):
        self.lifespan = max(0, self.lifespan - 1)
        if self.lifespan == 0:
            return "你因寿元耗尽，死亡。"
        return ""

    def heal(self):
        # 根据当前等级获取恢复量
        heal_amount = LEVEL_HEAL_AMOUNTS[self.level]
        self.hp = min(self.hp + heal_amount, self.max_hp)


class GameGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("文字修仙")
        self.player = Player()
        self.is_dead = False  # 新增状态标识，记录玩家是否死亡
        self.flag = 1
        # 设置窗口大小和布局
        root.geometry("800x600")
        root.configure(bg="#f0f0f0")

        # 创建主框架
        main_frame = tk.Frame(root, bg="#f0f0f0")
        main_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)

        # 添加作者、联系方式和版本说明
        author_info = "作者: 天狼(gitee:tianlang-cz) | 联系QQ:2090256385  | 1.3架构版"
        author_label = tk.Label(root, text=author_info, font=("Arial", 10), bg="#f0f0f0")
        author_label.pack(pady=5)
        # 创建显示区域
        self.result_text = tk.Text(main_frame, height=20, width=40, font=("Arial", 12), bg="#ffffff", bd=2, relief=tk.SOLID)
        self.result_text.pack(side=tk.LEFT, padx=10, pady=10, fill=tk.BOTH, expand=True)
        # 定义蓝色字体标签
        self.result_text.tag_configure("blue", foreground="blue")
        # 定义黑色字体标签
        self.result_text.tag_configure("black", foreground="black")
        # 定义红色字体标签
        self.result_text.tag_configure("red", foreground="red")

        # 创建状态栏
        self.status_label = tk.Label(main_frame, text=self.player.show_status(), justify=tk.LEFT, anchor="nw", font=("Arial", 12), bg="#ffffff", bd=2, relief=tk.SOLID)
        self.status_label.pack(side=tk.RIGHT, padx=10, pady=10, fill=tk.Y)

        # 创建按钮框架
        button_frame = tk.Frame(root, bg="#f0f0f0")
        button_frame.pack(pady=10)

        tk.Button(button_frame, text="修炼", command=self.train_action, font=("Arial", 12), width=10).grid(row=0, column=0, padx=5)
        tk.Button(button_frame, text="探索", command=self.explore_action, font=("Arial", 12), width=10).grid(row=0, column=1, padx=5)
        tk.Button(button_frame, text="挑战", command=self.challenge_action, font=("Arial", 12), width=10).grid(row=0, column=2, padx=5)
        tk.Button(button_frame, text="时光机", command=self.time_action, font=("Arial", 12), width=10).grid(row=0, column=3, padx=5)
        self.auto_train_var = tk.BooleanVar()
        self.auto_train_var.set(False)
        tk.Checkbutton(button_frame, text="开启自动修炼", variable=self.auto_train_var, command=self.toggle_auto_train, font=("Arial", 12)).grid(row=0, column=4, padx=5)
        tk.Button(button_frame, text="退出游戏", command=self.destory, font=("Arial", 12), width=10).grid(row=0, column=5, padx=5)

        self.auto_train_active = False
        self.update_lifespan()
        self.check_auto_train()
        self.countdown_id = None

    def train_action(self):
        if self.is_dead:
            return
        result = self.player.train()
        self.result_text.insert(tk.END, result + "\n", "blue")
        self.result_text.see(tk.END)
        self.update_status()
        self.check_game_over(result)

    def destory(self):
        messagebox.showinfo("已安全退出！", "Made by Tianlang\n感谢使用！")
        raise SystemExit

    def explore_action(self):
        if self.is_dead:
            return
        result = self.player.explore()
        self.result_text.insert(tk.END, result + "\n", "red")
        self.result_text.see(tk.END)
        self.update_status()
        self.check_game_over(result)

    def challenge_action(self):
        if self.is_dead:
            return
        result = self.player.challenge()
        self.result_text.insert(tk.END, result + "\n", "red")
        self.result_text.see(tk.END)
        self.update_status()
        self.check_game_over(result)

    def time_action(self):
        global timeRate
        if(timeRate==1 and self.flag==1):
            timeRate=0.5
            result = f"时光机减速，时间倍率为{timeRate}X"
        elif(timeRate==0.5):
            self.flag=0
            timeRate=1
            result=f"时光机已重置！"
        elif(timeRate>=1 and timeRate<10):
            timeRate+=1;
            result=f"时光机加速，时间倍率为{timeRate}X"
        else:
            timeRate=1
            result=f"时光机已重置！"
            self.flag=1
        self.result_text.insert(tk.END, result + "\n", "blue")
        self.result_text.see(tk.END)
        self.update_status()
        self.check_game_over(result)

    def toggle_auto_train(self):
        if self.is_dead:
            return
        if self.auto_train_var.get():
            self.auto_train_active = True
            self.auto_train()
        else:
            self.auto_train_active = False

    def auto_train(self):
        if self.is_dead:
            return
        if self.auto_train_active:
            result = self.player.train()
            self.result_text.insert(tk.END, result + "\n", "blue")
            self.result_text.see(tk.END)
            self.update_status()
            self.check_game_over(result)
            self.root.after(int(2000/timeRate), self.auto_train)

    def update_lifespan(self):
        if self.is_dead:
            return
        end_message = self.player.reduce_lifespan()
        if end_message:
            self.result_text.insert(tk.END, end_message + "\n", "black")
            self.result_text.see(tk.END)
            self.auto_train_active = False
            self.disable_buttons()
            self.is_dead = True  # 标记玩家已死亡
            self.start_again(5)
        self.update_status()
        self.root.after(int(2000/timeRate), self.update_lifespan)

    def update_status(self):
        if not self.is_dead:
            self.status_label.config(text=self.player.show_status())

    def check_game_over(self, result):
        global timeRate
        if "死亡" in result:
            self.auto_train_active = False
            self.disable_buttons()
            self.is_dead = True  # 标记玩家已死亡
            timeRate=1
            
            self.start_again(5)

    def disable_buttons(self):
            for child in self.root.winfo_children():
                if isinstance(child, tk.Frame):
                    for widget in child.winfo_children():
                        # 检查是否为按钮或复选框，并且不是退出游戏按钮
                        if (isinstance(widget, tk.Button) and widget.cget("text") != "退出游戏") or isinstance(widget,tk.Checkbutton):
                            widget.config(state=tk.DISABLED)

    def check_auto_train(self):
        if self.is_dead:
            return
        global year
        if not self.auto_train_active:
            year += 1
            location = random.choice(locations)
            subject = random.choice(subjects)
            event_type = random.randint(1, 100)
            if event_type <= 80:
                aResult = random.choice(result)
                event = f"在{aResult[0]}中，{aResult[1]}{aResult[2]}"
                event_text = f"第 {year} 年，{event}\n"
            elif event_type<=95:
                bad_event = random.choice(bad_events)
                if "生命值" in bad_event:
                    damage = random.randint(10, 30)
                    self.player.hp = max(0, self.player.hp - damage)
                    event_text = f"第 {year} 年，在{location}中，你" + bad_event.format(damage) + "\n"
                    if self.player.hp <= 0:
                        event_text += "你因生命值耗尽，死亡。"
                        self.check_game_over(event_text)
                else:
                    lifespan_loss = random.randint(20, 50)
                    self.player.lifespan = max(0, self.player.lifespan - lifespan_loss)
                    event_text = f"第 {year} 年，{location}中，{subject}" + bad_event.format(lifespan_loss) + "\n"
                    if self.player.lifespan <= 0:
                        event_text += "你因寿元耗尽，死亡。"
                        self.check_game_over(event_text)
            else:
                lucky_event = random.choice(lucky_events)
                lifespan_gain = random.randint(20, 70)
                self.player.lifespan+=lifespan_gain
                event_text = f"第 {year} 年，在{location}中，你" + lucky_event.format(lifespan_gain) + "\n"
            self.player.heal()  # 日常事件时恢复生命
            self.result_text.insert(tk.END, event_text, "black")
            self.result_text.see(tk.END)
            self.update_status()
        self.root.after(int(2000/timeRate), self.check_auto_train)

    def start_again(self, seconds):
        if self.is_dead:
            return
        if seconds > 0:
            self.result_text.insert(tk.END, f"游戏将在 {seconds} 秒后退出。\n", "black")
            self.result_text.see(tk.END)
            self.countdown_id = self.root.after(1000, self.start_again, seconds - 1)
        else:
            self.root.destroy()


if __name__ == "__main__":
    while True:
        root = tk.Tk()
        game = GameGUI(root)
        root.mainloop()